#include "osapi.h"
#include "cmsis_os2.h"
#include "cmsis_compiler.h"
#include "FreeRTOS.h"                   // ARM.FreeRTOS::RTOS:Core
#include "task.h"                       // ARM.FreeRTOS::RTOS:Core


/*---------------------------------------------------------------------------*/
#ifndef __ARM_ARCH_6M__
  #define __ARM_ARCH_6M__         0
#endif
#ifndef __ARM_ARCH_7M__
  #define __ARM_ARCH_7M__         0
#endif
#ifndef __ARM_ARCH_7EM__
  #define __ARM_ARCH_7EM__        0
#endif
#ifndef __ARM_ARCH_8M_MAIN__
  #define __ARM_ARCH_8M_MAIN__    0
#endif
#ifndef __ARM_ARCH_7A__
  #define __ARM_ARCH_7A__         0
#endif

#if   ((__ARM_ARCH_7M__      == 1U) || \
       (__ARM_ARCH_7EM__     == 1U) || \
       (__ARM_ARCH_8M_MAIN__ == 1U))
#define IS_IRQ_MASKED()           ((__get_PRIMASK() != 0U) || ((KernelIsRunning() == true) && (__get_BASEPRI() != 0U)))
#elif  (__ARM_ARCH_6M__      == 1U)
#define IS_IRQ_MASKED()           ((__get_PRIMASK() != 0U) &&  (KernelIsRunning() ==true))
#elif (__ARM_ARCH_7A__       == 1)
#define IS_IRQ_MASKED()           (0U)
#else
#define IS_IRQ_MASKED()           (__get_PRIMASK() != 0U)
#endif

#if    (__ARM_ARCH_7A__      == 1U)
/* CPSR mode bitmasks */
#define CPSR_MODE_USER            0x10U
#define CPSR_MODE_SYSTEM          0x1FU

#define IS_IRQ_MODE()             ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM))
#else
#define IS_IRQ_MODE()             (__get_IPSR() != 0U)
#endif

#define IS_IRQ()                  (IS_IRQ_MODE() || IS_IRQ_MASKED())


bool OsApi::KernelIsRunning()
{
    return osKernelGetState() == osKernelState_t::osKernelRunning;
}

void OsApi::KernelInitialize()
{
    osKernelInitialize();
}

void OsApi::KernelStart()
{
    osKernelStart();
}

void OsApi::KernelLock()
{
    osKernelLock();
}

void OsApi::KernelUnLock()
{
    osKernelUnlock();
}

void OsApi::KernelSuspend()
{
    // osKernelSuspend();
}

void OsApi::KernelResume(uint32_t sleep_ticks)
{
    // osKernelResume(sleep_ticks);
}

uint32_t OsApi::KernelEnterCritical()
{ 
    if (IS_IRQ())
    {
        return taskENTER_CRITICAL_FROM_ISR();
    }
    else 
    {
        taskENTER_CRITICAL();
        return 0;
    }
}

void OsApi::KernelExitCritical(uint32_t ret)
{
    if (IS_IRQ())
    {
        taskEXIT_CRITICAL_FROM_ISR(ret);
    }
    else 
    {
        taskEXIT_CRITICAL();
    }
}

bool OsApi::IsIRQ()
{
    return IS_IRQ();
}
